﻿using EnvDTE;
using Expect.Core;
using Expect.Core.BaseClasses;
using Expect.VisualStudio.Extensions.Services;
using System.Collections.Generic;

namespace Expect.VisualStudio.Extensions
{    
    public enum FixtureResolutionKind
    {
        None,
        Unknown,
        Description,
        BlocDefinition,
        Class,
        Method,
        MethodWithFixtureData
    }

    public enum FixtureResolutionTarget
    {
        None,
        Unknown,
        Container,
        Specification
    }

    public class SelectionResolution
    {
        public IExpectPackage ExpectPackage { get; private set; }

        public SelectionResolution(IExpectPackage pkg, ExpectItemResolution ctx)
        {
            ExpectPackage = pkg;
            Context = ctx;
        }

        public FixtureResolutionKind FixtureResKind { get; set; }

        public FixtureResolutionTarget FixtureResTarget { get; set; }

        public bool IsSpecification { get; set; }

        public bool IsComment { get; set; }

        public bool IsFixture
        {
            get
            {
                return FixtureResKind != FixtureResolutionKind.None && Fixture != null;
            }
        }

        public bool IsResolvedFixture
        {
            get
            {
                if (
                    FixtureResKind != FixtureResolutionKind.None &&
                    FixtureResKind != FixtureResolutionKind.Unknown &&
                    FixtureResKind != FixtureResolutionKind.Description &&
                    FixtureResKind != FixtureResolutionKind.BlocDefinition
                )
                {
                    return true;
                }

                return false;
            }
        }

        public ExpectItemResolution Context { get; set; }

        public CurrentTextSelection Selection { get; set; }        

        public ProjectItem Target { get; set; }

        public TextPoint TargetPoint { get; set; }

        public ClassMap SpecItem { get; set; }
        
        public SpecificationDefinition Specification { get; set; }

        public FixtureDefinition Fixture { get; set; }

        public ClassMap FixtureMap { get; set; }

        public FixtureRow ClickedRow { get; set; }

        public INameProvider NameProvider { get; private set; }

        internal void Resolve()
        {
            NameProvider = new DefaultNameProvider();
            string trimmedSelectionText = Selection.Text.Trim();

            if (trimmedSelectionText != null && trimmedSelectionText.StartsWith("#"))
            {
                FixtureResKind = FixtureResolutionKind.Description;
                IsComment = true;
                return;
            }

            if (trimmedSelectionText != null && trimmedSelectionText.StartsWith("@"))
            {
                FixtureResKind = FixtureResolutionKind.BlocDefinition;
                ResolveSpecification(trimmedSelectionText);
                return;
            }

            ResolveFixture();
        }

        private void ResolveFixture()
        {
            FixtureResKind = FixtureResolutionKind.Unknown;
            FixtureResTarget = FixtureResolutionTarget.Unknown;

            var fixtureResolve = new FixtureResolution(this);
            fixtureResolve.Resolve();            
        }

        private void ResolveSpecification(string trimmedSelectionText)
        {
            IsSpecification = true;
        }
    }

    public class CurrentTextSelection
    {
        public int StartLine { get; set; }

        public int StartCol { get; set; }

        public int EndLine { get; set; }

        public int EndCol { get; set; }

        public string Text { get; set; }

        public string FullText { get; set; }
    }
}
